Exercises
Toonie Clicker
“Cookie Clicker” is a casual web-based game. You click a big cookie to earn points, and then use those points to buy items that click the cookie for you.
In this exercise, we'll build a simple version of the game. Instead of a cookie, we'll use a Canadian toonie.
Acceptance criteria:
- “Your coin balance”, at the bottom of the page, should update to show the value of
numOfCoins
. - Clicking the coin should increment this value by 2 (since it's a $2 coin).
Code Playground
Solution:
Shopping List
Unsatisfied with the plethora of shopping-list applications out there, we've decided to build our own!
A fellow developer has implemented the design in JSX, but it's entirely static. Your job is to update the code so that it works, like this:
Note: This exercise touches on some ideas we haven't explicitly learned about yet. It's OK if you can't come up with the solution; the important thing is that you give it a shot!
Acceptance Criteria:
- The shown list of items should be driven from React state. We can remove the placeholder foods, and start with an empty list
- Submitting the form should add a new item to the list, and show it in the UI
- When submitting the form, the text input should be reset, so that it's empty. This way, users can easily add multiple items without having to erase their previous entry.
- There should be no “key” warnings in the console. Ideally, you shouldn't use the index for the key.
Code Playground
Solution:
In this video, I use the “property value shorthand” when creating new items, for the label
property. You can learn more about this in the “Property Value Shorthand” lesson 👀 in the JavaScript Primer.
Why not pass the setter function directly?
Several students have wondered: wouldn't it be simpler to pass the setItems
function down to AddNewItemForm
?
Something like this:
function AddNewItemForm({ items, setItems }) { const [label, setLabel] = React.useState('');
return ( <div className="new-list-item-form"> <form onSubmit={(event) => { event.preventDefault();
const newItem = { label, id: Math.random(), };
const nextItems = [...items, newItem]; setItems(nextItems);
setLabel('') }} > {/* Everything else unchanged */} </form> </div> );}
export default AddNewItemForm;
This is a valid solution, and there's nothing wrong with it, but in my opinion, it's not the best approach to this problem.
Later in this course, in Module 5, we'll dig into exactly why I prefer not to pass the state-setter function directly in most cases.
For now, feel free to structure things however you like, especially if you're newer to React! My explanations will make more sense once you have more first-hand experience solving these sorts of problems.